function profiles = PulseCompression(echo, options)
    c = 3e8;
    L = numel(echo.FastTime);
    fs = (L - 1)/(echo.FastTime(end) - echo.FastTime(1));
    sref = newSignal(options.Signal); 
    TotalTime = sref.PulseWidth + L / fs;
    TotalSamples = ceil(TotalTime * fs);
    M = ceil(sref.PulseWidth * fs);
    assert(TotalSamples >= L + M - 1);
    [profiles.Spectrum, profiles.Frequency] = doFFT(echo.Amplitude, echo.FastTime, 1, 'padding', TotalSamples - L);
    s0 = sref.getSamples(profiles.Frequency, echo.CarrierFrequency);
    for i = 1:numel(echo.SlowTime)
        profiles.Spectrum(:,i) = profiles.Spectrum(:,i) .* conj(s0.Spectrum); 
    end
    [Amplitude, FastTime] = doIFFT(profiles.Spectrum, profiles.Frequency, 1, ...
                                   'offset', echo.FastTime(1));
    Amplitude = Amplitude(1:(L - M), :);
    Range = FastTime(1:size(Amplitude,1))*c/2;
    if isfield(options, 'RangeStart')
        index = Range >= options.RangeStart;
        Amplitude = Amplitude(index, :);
        Range = Range(index);
        if isfield(options, 'RangeWindow')
            index = Range < options.RangeStart + options.RangeWindow;
            Amplitude = Amplitude(index, :);
            Range = Range(index);
        end
    end
    profiles.Range = Range;
    profiles.Amplitude = Amplitude;
    profiles.SlowTime = echo.SlowTime;
    if isfield(options, 'ShowPulseCompression') && options.ShowPulseCompression
        figure('Name', 'PulseCompression', 'NumberTitle', 'off', 'WindowStyle', 'docked');
        subplot(221);
        plot(echo.FastTime, real(echo.Amplitude));
        subplot(222);
        plot(s0.Time, real(s0.Amplitude));
        subplot(223);
        plot(profiles.Range, real(profiles.Amplitude));
        xlabel('Fast Time[s]');
        % legend('Echo', 'Reference', 'Profile');
    end
    if isfield(options, 'ShowProfileHistory') && options.ShowProfileHistory
        figure('Name', 'ProfileHistory', 'NumberTitle', 'off', 'WindowStyle', 'docked');
        subplot(121);
        imagesc(profiles.SlowTime, profiles.Range, abs(profiles.Amplitude));
        set(gca, 'YDir', 'normal');
        xlabel('Slow Time[s]');
        ylabel('Range[m]');
        subplot(122);
        slowIndex = ceil(numel(profiles.SlowTime)/2);
        [~, rangeIndex] = max(abs(profiles.Amplitude(:, slowIndex)));
        % plot(profiles.Range, abs(profiles.Amplitude(:, slowIndex)));
        % hold on; plot(profiles.Range(rangeIndex), abs(profiles.Amplitude(rangeIndex,slowIndex)), 'o');
        plot(profiles.SlowTime, real(profiles.Amplitude(rangeIndex,:)));
        xlabel('Slow Time[s]');
        title(sprintf('RangeIndex = %d', rangeIndex));
    end
end